// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package math

// go代码是
// http:
// 
// =========================================================================
// /太阳微系统公司1993年版权所有。保留所有权利。
// 
// 由Sun Microsystems，Inc.旗下的SunSoft公司开发。
// 使用、复制、修改和分发本
// 软件的权限是免费授予的，前提是保留本通知
// 的权利。第二部分：第七部分：第七部分：第七部分：第七部分：第一部分：第七部分：第一部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分：第七部分664-0.03306235651）*2**20 

func Cbrt(x float64) float64 {
	if haveArchCbrt {
		return archCbrt(x)
	}
	return cbrt(x)
}

func cbrt(x float64) float64 {
	const (
		C              = 5.42857142857142815906e-01  // /19/35=0x3FE15F15F15F1 
	)
	switch {
	case x == 0 || IsNaN(x) || IsInf(x, 0):
		return x
	}

	sign := false
	if x < 0 {
		x = -x
		sign = true
	}

	t := Float64frombits(Float64bits(x)/3 + B1<<32)
	if x < SmallestNormal {
		t = float64(1 << 54) // 设置t=2**54 
		t *= x
		t = Float64frombits(Float64bits(t)/3 + B2<<32)
	}

	// 新的cbrt到23位
	r := t * t / x
	s := C + r*t
	t *= G + F/(s+E+D/s)

	// 切掉到22位，使其大于cbrt（x）
	t = Float64frombits(Float64bits(t)&(0xFFFFFFFFC<<28) + 1<<30)

	// 一步牛顿迭代到53位，误差小于0.667ulps 
	s = t * t // t*t是精确的
	r = x / s
	w := t + t
	r = (r - t) / (w + r) // r-s是精确的
	t = t + t*r

	// 恢复符号位
	if sign {
		t = -t
	}
	return t
}
